package com.laf.manage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.laf.common.constant.CacheConstants;
import com.laf.common.core.domain.model.LoginMobileUser;
import com.laf.common.core.page.TableDataInfo;
import com.laf.common.core.redis.RedisCache;
import com.laf.common.exception.ServiceException;
import com.laf.common.utils.SecurityUtils;
import com.laf.common.utils.StringUtils;
import com.laf.manage.domain.dto.CommentsDTO;
import com.laf.manage.domain.dto.DynamicCountDTO;
import com.laf.manage.domain.dto.PageDTO;
import com.laf.manage.domain.po.Comments;
import com.laf.manage.domain.po.Dynamic;
import com.laf.manage.domain.vo.CommentsVO;
import com.laf.manage.enums.VerifyStatusEnum;
import com.laf.manage.mapper.mp.CommentsMapper;
import com.laf.manage.mapper.mp.DynamicMapper;
import com.laf.manage.service.ICommentsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 评论管理Service业务层处理
 *
 * @author zian
 * @date 2024-11-09
 */
@Service
public class CommentsServiceImpl extends ServiceImpl<CommentsMapper, Comments> implements ICommentsService {

    @Autowired
    private CommentsMapper commentsMapper;

    @Autowired
    private DynamicMapper dynamicMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询评论管理列表
     *
     * @param comments 评论管理
     * @return 评论管理
     */
    @Override
    public List<Comments> selectCommentsList(Comments comments) {
        List<Comments> commentsList = commentsMapper.selectList(buildQueryWrapper(comments));
        return commentsList;
    }

    /**
     * 查询评论管理列表
     *
     * @param comments 评论管理
     * @return 评论管理集合
     */
    @Override
    public TableDataInfo selectCommentsVOList(Comments comments, Integer pageNum, Integer pageSize) {
        Page<Comments> page = Page.of(pageNum, pageSize);
        List<CommentsVO> voList = getBaseMapper().selectCommentsVOList(page, comments);

        if (CollUtil.isEmpty(voList)) {
            TableDataInfo.empty();
        }

        // 封装分页结果
        return TableDataInfo.success(page.getTotal(), voList);
    }

    /**
     * 查询评论管理列表
     *
     * @param comments 评论管理
     * @return 评论管理集合
     */
    @Override
    public PageDTO<CommentsVO> getCommentsVOList(Comments comments, Integer pageNum, Integer pageSize) {
        Page<Comments> page = Page.of(pageNum, pageSize);
        List<CommentsVO> voList = getBaseMapper().selectCommentsVOList(page, comments);

        if (CollUtil.isEmpty(voList)) {
            return PageDTO.empty(0L, 0L);
        }

        // 封装分页结果
        return PageDTO.of(page.getTotal(), (long) page.getPages(), voList);
    }

    /**
     * 批量通过审核
     *
     * @param commentsIds 评论id集合
     */
    @Override
    public void passCommentsByIds(List<Long> commentsIds) {
        String username = SecurityUtils.getUsername();
        // 批量修改
        boolean b = lambdaUpdate()
                .in(Comments::getId, commentsIds)
                .set(Comments::getVerifyStatus, VerifyStatusEnum.VERIFY_PASS)
                .set(Comments::getUpdateTime, LocalDateTime.now())
                .set(Comments::getUpdateBy, username)
                .update();
        if (!b) throw new ServiceException("批量通过审核失败");
    }

    @Override
    public void notPassCommentsByIds(List<Long> commentsIds) {
        String username = SecurityUtils.getUsername();
        // 批量修改
        boolean b = lambdaUpdate()
                .in(Comments::getId, commentsIds)
                .set(Comments::getVerifyStatus, VerifyStatusEnum.VERIFY_NOT_PASS)
                .set(Comments::getUpdateTime, LocalDateTime.now())
                .set(Comments::getUpdateBy, username)
                .update();
        if (!b) throw new ServiceException("批量通过审核失败");

        // 评论数量减一
        for (Long commentsId : commentsIds) {
            Object cacheMapValue = redisCache.getCacheMapValue(CacheConstants.COMMENTS_PREFIX, commentsId.toString());
            if (cacheMapValue != null) {
                redisCache.setCacheMapValue(CacheConstants.COMMENTS_PREFIX, commentsId.toString(), (Integer) cacheMapValue - 1);
            }
        }

    }

    /**
     * 新增评论管理
     *
     * @param dto message 评论内容  dynamicId 动态id
     */
    @Override
    public void addComments(CommentsDTO dto) {
        // 1. 校验动态
        Dynamic dynamic = dynamicMapper.selectById(dto.getDynamicId());
        if (dynamic == null) {
            throw new ServiceException("动态不存");
        }

        if (!dynamic.getVerifyStatus().equals(VerifyStatusEnum.VERIFY_PASS)) {
            throw new ServiceException("动态未通过审核");
        }

        // 封装 po
        Comments comments = BeanUtil.copyProperties(dto, Comments.class);
        LoginMobileUser loginUser = SecurityUtils.getMobileLoginUser();
        comments.setCreateUserId(loginUser.getUserId());
        comments.setCreateBy(loginUser.getUsername());
        comments.setUpdateBy(loginUser.getUsername());
        comments.setVerifyStatus(VerifyStatusEnum.WAIT_VERIFY.getCode());
        boolean b = save(comments);
        if (!b) throw new ServiceException("添加评论失败");

        // 添加缓存
        Object cacheMapValue = redisCache.getCacheMapValue(CacheConstants.COMMENTS_PREFIX, dto.getDynamicId().toString());
        if (cacheMapValue != null) {
            redisCache.setCacheMapValue(CacheConstants.COMMENTS_PREFIX, dto.getDynamicId().toString(), (Integer) cacheMapValue + 1);
        } else {
            redisCache.setCacheMapValue(CacheConstants.COMMENTS_PREFIX, dto.getDynamicId().toString(), 1);
        }


    }

    @Override
    @Transactional
    public void delByIds(List<Long> ids) {
        // 删除评论
        boolean b = removeByIds(ids);

        // 重新缓存评论数
        List<Comments> commentsList = list(
                Wrappers.<Comments>lambdaQuery()
                        .select(Comments::getDynamicId)
                        .in(Comments::getId, ids)
        );
        List<Long> dynamicIds = commentsList.stream()
                .map(Comments::getDynamicId)
                .collect(Collectors.toList());

        List<DynamicCountDTO> dynamicCountDTOS = getBaseMapper().dynamicCommentCountByDynamicIds(dynamicIds);
        Map<String, Integer> commentMap = dynamicCountDTOS.stream()
                .collect(Collectors.toMap(item -> item.getDynamicId().toString(), DynamicCountDTO::getCount));
        commentMap.forEach((k, v) -> {
            redisCache.setCacheMapValue(CacheConstants.COMMENTS_PREFIX, k, v);
        });
    }

    /**
     * 构建查询条件
     *
     * @param query 查询条件
     * @return 查询条件
     */
    private LambdaQueryWrapper<Comments> buildQueryWrapper(Comments query) {
        Map<String, Object> params = query.getParams();
        LambdaQueryWrapper<Comments> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(query.getMessage()), Comments::getMessage, query.getMessage());
        lqw.eq(query.getDynamicId() != null, Comments::getDynamicId, query.getDynamicId());
        lqw.eq(query.getVerifyStatus() != null, Comments::getVerifyStatus, query.getVerifyStatus());
        lqw.eq(query.getCreateUserId() != null, Comments::getCreateUserId, query.getCreateUserId());
        lqw.orderByDesc(Comments::getCreateTime);
        return lqw;
    }

}
